home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / TreeView / Tree.m < prev    next >
Text File  |  1995-06-12  |  4KB  |  140 lines

  1. //
  2. //    Tree.m -- a generic class to build tree data structures
  3. //        This class requires the String class, also by Don Yacktman.
  4. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  5. //                All rights reserved.
  6. //
  7. //        You may use and copy this class freely as long as you
  8. //        comply with the following terms:
  9. //            (1) If you use this class in an application which you
  10. //                intend to sell commercially, as shareware, or otherwise,
  11. //                you may only do so with express written permission
  12. //                of the author.  Use in applications which will
  13. //                be distributed free of charge is encouraged.
  14. //            (2) You must include the source code to this object and
  15. //                all accompanying documentation with your application,
  16. //                or provide it to users if requested, free of charge.
  17. //            (3) Do not remove the author's name or any of the
  18. //                copyright notices
  19. //
  20.  
  21. #import "Tree.h"
  22.  
  23. @implementation Tree
  24.  
  25. - init            // special init for this class
  26. {
  27.     [self initLabel:""];
  28.     return self;
  29. }
  30.  
  31. - initLabel:(const char *)newLabel
  32. {
  33.     [super init];
  34.     notCollapsed = YES;
  35.     // set up a list class to hold pointers to other Tree objects (branches).
  36.     branches = [[List alloc] init];    // make a dynamic-sized array of objects
  37.     label = [[String alloc] init];    // make a string for the label
  38.     [label setString:newLabel];
  39.     return self;
  40. }
  41.  
  42. - initLabelString:string    // send in a String object
  43. {
  44.     [self init];
  45.     if (label) [label free];
  46.     label = string;
  47.     return self;
  48. }
  49.  
  50. - setLabel:(const char *)newLabel
  51. {
  52.     [label setString:newLabel];
  53.     return self;
  54. }
  55.  
  56. - free            // clean up our mess
  57. {
  58.     [branches freeObjects];    // free the branches we're responsible for
  59.     // (I assumed that each branch only has one parent...if that's not
  60.     // the case, then the above line should be axed.)
  61.     [branches free];        // get rid of the List object
  62.     return [super free];
  63. }
  64.  
  65. - addBranch:child    // add a new child node
  66. {    // add to the end of the "branches" List object
  67.     return [branches addObject:child];
  68. }
  69.  
  70. - dumpTree:(NXStream *)file level:(int)lev indent:(const char *)ind
  71. {
  72.     int i; BOOL doKids;
  73.     
  74.     for (i=0; i<lev; i++) NXPrintf(file, "%s", ind);    // indent
  75.     NXPrintf(file, "%s", [label stringValue]);            // and print label
  76.     doKids = [self moreData:file level:lev indent:ind];
  77.     NXPrintf(file, "\n", [label stringValue]);            // print newline
  78.     if (doKids)
  79.         for (i=0; i<[branches count]; i++)                // then do children
  80.             [[branches objectAt:i] dumpTree:file level:(lev + 1) indent:ind];
  81.     return self;
  82. }
  83.  
  84. - (BOOL)moreData:(NXStream *)file level:(int)lev indent:(const char *)ind
  85. {    // Subclass responsibility -- you can dynamically control collapsing
  86.     // (for example, cut off at a certain level, etc.) and also add info
  87.     // to the end of a dumped node's line from here.  Be sure to message
  88.     // super when you override this method; if this method returns a NO
  89.     // then you should return a NO, regardless.  Don't just use the
  90.     // notCollapsed instance var, since it may change in the future; look
  91.     // at the return value from super!
  92.     //
  93.     // Here's how you might override to keep from printing levels deeper
  94.     // than level 2 (remember that the root level is zero):
  95.     //
  96.     //    - (BOOL)moreData:(NXStream *)file level:(int)lev indent:(const char *)ind
  97.     //    {
  98.     //        if ((lev > 2) || ![super moreData:file level:lev indent:ind])
  99.     //            return NO;
  100.     //        return YES;
  101.     //    }
  102.     //
  103.     return notCollapsed;
  104. }
  105.  
  106. - (int)width
  107. {
  108.     int num = [branches count];
  109.     int i, count = 0;
  110.     
  111.     if (!num) return 1;    // No children, so we're only one node wide...
  112.     
  113.     // have kids, so sum up their widths.
  114.     for (i=0; i<num; i++) count += [[branches objectAt:i] width];
  115.     return count;
  116. }
  117.  
  118. - (int)depth
  119. {
  120.     int num = [branches count];
  121.     int i, temp, deepest = 1;
  122.     
  123.     if (!num) return 1;    // No children, so only one node deep
  124.     
  125.     // have kids, so see which branch is deepest.
  126.     for (i=0; i<num; i++) {
  127.         temp = [[branches objectAt:i] depth];
  128.         if (temp > deepest) deepest = temp;
  129.     }
  130.     return (deepest + 1);    // we are one deeper than the deepest child.
  131. }
  132.  
  133. - branches { return branches; }
  134. - collapse { notCollapsed = NO; return self; }
  135. - uncollapse { notCollapsed = YES; return self; }
  136. - (BOOL)collapsed { return !notCollapsed; }
  137. - (const char *)label { return [label stringValue]; }
  138.  
  139. @end
  140.